<?php

namespace app\api\controller;

use app\common\model\GoodsCards;
use app\common\model\UserCards;
use EasyWeChat\Factory;
// use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment;
use think\Controller;
use think\Db;
use think\Exception;
use think\Log;
use think\Model;

class WxPay extends Controller
{
    protected $Config;
    protected $Config2;

    protected $App;
    protected $NotifyUrl;
    protected $NotifyUrl2;
    protected $NotifyUrl3;
    protected $Payment;
    protected $merchantPay;

    public function _initialize()
    {
        parent::_initialize();

        $this->Config = [
            'debug' => true,
            'app_id' => config('weixin.mini_appid'),
            'secret' => config('weixin.mini_appsecret'),
            'mch_id' => config("weixin.mch_id"),
            'log' => ['level' => 'debug', 'file' => ROOT_PATH . 'runtime/easywechat.log'],
        ];

        $this->Config2 = [
            'app_id' => config('weixin.mini_appid'),
            'secret' => config('weixin.mini_appsecret'),
            'mch_id' => config("weixin.mch_id"),
            'key' =>    config("weixin.wechat_key"),
            'cert_path' => ROOT_PATH . 'public/cert/apiclient_cert.pem', // XXX: 绝对路径！！！！
            'key_path' => ROOT_PATH . 'public/cert/apiclient_key.pem', // XXX: 绝对路径！！！！
            'log' => ['level' => 'debug', 'file' => ROOT_PATH . 'runtime/easywechat.log'],
        ];


        $this->NotifyUrl = 'https://jkgl.neweyes.cc/api/Wx_Pay/WxOrderNotify';
        try {
            $this->App = Factory::officialAccount($this->Config);
        } catch (\Exception $e) {
            \think\Log::error('初始化失败：' . $e->getMessage());
        }

        try {
            // 检查配置文件

            $this->Payment = Factory::Payment($this->Config2);
        } catch (Exception $e) {
            \think\Log::error('初始化失败：' . $e->getMessage());
        }

    }
    public function  index()
    {
        dump($this->Config);
    }

    //创建微信统一订单--支付
    public function union_order($orderInfo)
    {

        if ($orderInfo['money'] * 100 < 1) {
            new \app\common\exception\Exception('至少支付0.01元');
            return false;
        }
        $payment = $this->Payment;
        $cepro =[];
        if (count($cepro)>0) {

            $ceshi = db('user')->where(['id' => ['in', $cepro]])->select();

            foreach ($ceshi as &$vv) {
//                if ($orderInfo['openid'] == $vv['openid']) {
                    $orderInfo['money'] = 0.01;
                //}
            }

        }

        $attributes = [
            'openid' => $orderInfo['openid'],
            'body' => $orderInfo['body'],
            'detail' => $orderInfo['detail'],
            'out_trade_no' => $orderInfo['ordernum'],
            'total_fee' => $orderInfo['money'] * 100,
            'trade_type' => 'JSAPI',
            'time_start' => date('YmdHis'),
            'time_expire' => date('YmdHis', strtotime('+1 year')),
            'notify_url' =>  $this->NotifyUrl,
        ];
        Log::error($attributes);
        $result = $payment->order->unify($attributes);



        if ($result['return_code'] == 'SUCCESS') {
            if(empty($result['prepay_id'])){
                return  false;
            }
            $prepayId = $result['prepay_id'];
            if (!$prepayId) {
                return false;
            }
            $jssdk = $payment->jssdk;
            $config = $jssdk->sdkConfig($prepayId);
            $config['timeStamp'] = $config['timestamp']; //此处需要将小写s变为大写
            Log::error($config);

            return $config; //（对应原理4）

        } else {
            new \app\common\exception\Exception($result['return_msg']??'');
            return false;
        }

    }




    //微信支付订单支付回调
    public function WxOrderNotify()
    {

        $payment = $this->Payment;
        $response = $payment->handlePaidNotify(function ($message, $fail) {

            if ($message['return_code'] === 'SUCCESS' && $message['result_code'] === 'SUCCESS') {

                //$order_info = db('order')->where('order_no', 'like', $message['out_trade_no'] . '%')->find();
                //你可以在此编写订单逻辑
                $orderm =new \app\common\model\Order();

                $order = $orderm->where('order_sn', $message['out_trade_no'])->find();

                if (!$order || $order->status > 0) {
                    // 订单不存在，或者订单已支付
                    Log::error('订单不存在，或者订单已支付');
                    //return $fail('');
                    return 'Order not exist.';
                    // return $this->payResponse($pay, $payment);
                }


                // Db::startTrans();
                try {
                    $pay_fee        = $message['total_fee'] / 100;
                    $transaction_id = $message['transaction_id'];
                    $notify = [
                        'order_sn' => $message['out_trade_no'],
                        'transaction_id' => $transaction_id,
                        'notify_time' => date('Y-m-d H:i:s', strtotime($message['time_end'])),
                        'buyer_email' => $message['openid'],
                        'payment_json' => json_encode($message),
                        'pay_fee' => $pay_fee,
                        'pay_type' => 'wechat'              // 支付方式
                    ];
                    $orderm->where(['id'=>$order['id']])->update(['pay_fee'=>$pay_fee,
                        'canuse_appoints'=>$order['appoints'],'pay_status'=>20,'status'=>1,'order_status'=>1,
                        'buyer_openid'=>$message['openid'],'transaction_id'=>$transaction_id,
                        'paytime'=>time(),
                        'payment_json'=>json_encode($message)]);
                    $order_items = db('order_item')->where(['order_id'=>$order['id']])->select();
                    $time =time();
                    foreach ($order_items as $k=>$v){
                        db('order_item')->where(['id'=>$v['id']]) ->update(['canuse_num'=>$v['rights_num']*$v['goods_num']]);
//                        for($i=1;$i<=$v['goods_num'];$i++) {
//
//                        }
                        $msvae= ['user_id' => $order['user_id'], 'order_item_id' => $v['id'],
                            'order_id' => $order['id'], 'hospital_ids' => $v['hospital_ids'],
                            'goods_id' => $v['goods_id'], 'card_id' => 0,'type'=>1,
                            'rights_card' => $v['rights_card'], 'rights_title' => $v['rights_title'],
                            'rights_nums' => $v['rights_num']*$v['goods_num'], 'can_uses' => $v['rights_num']*$v['goods_num'],
                            'rights_memo'=>$v['rights_memo'],'rights_desc'=>$v['rights_desc'],
                            'rights_tags'=>$v['tags'],
                            'is_all'=>$v['is_all'],
                            'rights_endtime' =>$v['rights_endtime'], 'rights_content' => $v['rights_content'],
                            'status'=>1,'createtime'=>time(),'updatetime'=>time()
                        ];
                        $card_id=(new UserCards())->insertGetId($msvae);
                        $tags_ids=  \db('order_item_examine')->where(['order_item_id'=>$v['id']])->select();
                        $m_saves=[];
                        $createtime=time();
                        foreach ($tags_ids as $k1=>$v1){
                            $m_saves[]=['user_id'=>$order['user_id'],
                                'card_id'=>$card_id,'tag_id'=>$v1['tag_id'],
                                'tag_name'=>$v1['tag_name'],'createtime'=>$createtime];
                        }
                        \db('user_card_examines')->insertAll($m_saves);
                    }
                    Db::commit();

//
                    return true;
                } catch (Exception $exception) {
                    Db::rollback();
                    return false;
                }
            } else {
                Log::error($message);

                return $fail('失败');

            }
        });

        return $response;
    }
    public function addUseCards($user_id,$order_id,$items,$num)
    {
        $cards=[];

        $c=$num;//生成1000组卡号密码
        if(!$c){
            $this->error('请填写生成卡密数量');
        }
        if(!is_numeric($c)&&$c<1){
            $this->error('请填写正确的生成卡密数量');
        }

        $time =time();
        $mcrads=[];
        for($x=0;$x< $c;$x++){
            $cards[$x]['goods_id']     =$items['goods_id'];
            $card_no=$this->getRandnumber().$this->getRandnumber();
            $cards[$x]['goods_cards_no']=$card_no;
            $mcrads[]=$mcrads;
            $cards[$x]['goods_card_key']=$this->makeCardPassword();
            $cards[$x]['user_id']=$user_id;
            $cards[$x]['use_status']=1;
            $cards[$x]['use_time']=$time;
        }
        if(count($cards)>100){
            $num = 100;//每次导入条数
            $limit = ceil(count($cards)/$num);
            for($i=1;$i<=$limit;$i++){
                $offset=($i-1)*$num;
                $data=array_slice($cards,$offset,$num);
                $result=  (new GoodsCards())->saveAll($data);
            };
        }else{
            $result=  (new GoodsCards())->saveAll($cards);
        }
        $order_cards= (new GoodsCards())
            ->where(['status'=>1,'goods_id'=>$items['goods_id'],'user_id'=>$user_id,'use_status'=>1])
            ->where('goods_cards_no','in',implode(',',$mcrads))
            ->column('id');
        $msvae=[];
        foreach ($order_cards as $k2=>$v2){
            $msvae[]=['user_id'=>$user_id,'order_item_id'=>$items['id'],
                'order_id'=>$order_id,'hospital_ids'=>$items['hospital_ids'],
                'goods_id'=>$items['goods_id'],'card_id'=>$v2['id'],
                'rights_card'=>$items['rights_card'],'rights_title'=>$items['rights_title'],
                'rights_nums'=>$items['rights_num'],'can_uses'=>$items['rights_nums'],
                'rights_endtime'=>$items['rights_endtime'],'rights_content'=>$items['rights_content'],
                'rights_memo'=>$items['rights_memo'],'rights_desc'=>$items['rights_desc'],
                'status'=>1
            ];
        }
        if(count($msvae)>100){
            $num = 100;//每次导入条数
            $limit = ceil(count($msvae)/$num);
            for($i=1;$i<=$limit;$i++){
                $offset=($i-1)*$num;
                $data=array_slice($msvae,$offset,$num);
                $result= (new UserCards())->saveAll($data);
            };
        }else{
            $result= (new UserCards())->saveAll($msvae);
        }

    }
 public   function makeCardPassword() {
        $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $rand = $code[rand(0,25)]
            .strtoupper(dechex(date('m')))
            .date('d').substr(time(),-5)
            .substr(microtime(),2,5)
            .sprintf('%02d',rand(0,99));
        for(
            $a = md5( $rand, true ),
            $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV',
            $d = '',
            $f = 0;
            $f < 6;
            $g = ord( $a[ $f ] ),
            $d .= $s[ ( $g ^ ord( $a[ $f + 6 ] ) ) - $g & 0x1F ],
            $f++
        );
        return  $d;
    }
    /**
     * 生成不重复的随机数字
     * @param  int $start  需要生成的数字开始范围
     * @param  int $end    结束范围
     * @param  int $length 需要生成的随机数个数
     * @return number      生成的随机数
     */
  public  function getRandnumber ($start=0,$end=9,$length=8){
        //初始化变量为0
        $connt = 0;
        //建一个新数组
        $temp = array();
        while($connt < $length){
            //在一定范围内随机生成一个数放入数组中
            $temp[] = mt_rand ($start, $end);
            //$data = array_unique($temp);
            //去除数组中的重复值用了“翻翻法”，就是用array_flip()把数组的key和value交换两次。这种做法比用 array_unique() 快得多。
            $data = array_flip(array_flip($temp));
            //将数组的数量存入变量count中
            $connt = count($data);
        }
        //为数组赋予新的键名
        shuffle($data);
        //数组转 字符串
        $str=implode(",", $data);
        //替换掉 逗号
        $number=str_replace(',', '', $str);

        return $number;
    }


    public function applyRefund($order_id, $refund_id, $to_back_fee, $refund_type = 'order', $reason = '')
    {

        $payment = $this->Payment;
        $orderModel = db('order_aftersale'); //TODO 可能替换
        $orderInfo = $orderModel->where('id', $refund_id)->find();
        $order = db('order')->where('id', $order_id)->find();
        $to_back_fee = intval(strval($to_back_fee));
        $wx_trade_no = $order['order_sn'];
        $wx_pay = intval(strval($order['pay_fee']*100));



//        $order_no =explode('-',$order['order_no']);
//        if(count($order_no)>1){
//            $wx_trade_no =$order_no[0];
//        }


        $refund_no = $orderInfo['aftersale_sn'].'_r';

        if (!$orderInfo) {
            return ['status' => false, 'msg' => '退款订单不存在'];
        }
        if (!$order) {
            return ['status' => false, 'msg' => '订单不存在'];
        }

        if ($to_back_fee >$wx_pay) {
            return ['status' => false, 'msg' => '退款金额大于支付金额'];
        }



        try {
            // dump($wx_trade_no);
            // dump($refund_no);
            // dump($wx_pay);
            // dump($to_back_fee);

            // die;
            $result = $payment->refund->byOutTradeNumber($wx_trade_no, $refund_no, $wx_pay, intval($to_back_fee)); // 总金额 100， 退款 80，操作员：商户号
            // $result = $payment->order->unify($attributes);


            if ('SUCCESS' != $result['return_code'] || "SUCCESS" != $result['result_code']) {
                //pubu("订单号：{$order_no} 因{$reason} 申请的微信退款失败, 原因：{$result['return_msg']}");
                return ['status' => false, 'msg' => "订单号：{$order['transaction_id']} 因{$reason} 申请的微信退款失败, 原因：{$result['err_code_des']}"];
            } else {

                return ['status' => true, 'msg' => '退款成功'];
            }
        } catch (\Exception $e) {
            return ['status' => false, 'msg' => "订单号：{$order['transaction_id']} 因{$reason} 申请的微信退款失败, 原因：{$e->getMessage()}"];
        }
    }

    public function applyRefund1($order_id, $refund_id, $to_back_fee, $refund_type = 'order', $reason = '')
    {

        $payment = $this->Payment;
        $orderModel = db('order_aftersale'); //TODO 可能替换
        $orderInfo = db('order')->where('id', $refund_id)->find();
        $order = db('order')->where('id', $order_id)->find();
        $to_back_fee = intval(strval($to_back_fee));
        $wx_trade_no = $order['order_sn'];
        $wx_pay = intval(strval($order['pay_fee']*100));



//        $order_no =explode('-',$order['order_no']);
//        if(count($order_no)>1){
//            $wx_trade_no =$order_no[0];
//        }


        $refund_no = $orderInfo['order_sn'].'_r';

        if (!$orderInfo) {
            return ['status' => false, 'msg' => '退款订单不存在'];
        }
        if (!$order) {
            return ['status' => false, 'msg' => '订单不存在'];
        }

        if ($to_back_fee >$wx_pay) {
            return ['status' => false, 'msg' => '退款金额大于支付金额'];
        }



        try {
            // dump($wx_trade_no);
            // dump($refund_no);
            // dump($wx_pay);
            // dump($to_back_fee);

            // die;
            $result = $payment->refund->byOutTradeNumber($wx_trade_no, $refund_no, $wx_pay, intval($to_back_fee)); // 总金额 100， 退款 80，操作员：商户号
            // $result = $payment->order->unify($attributes);


            if ('SUCCESS' != $result['return_code'] || "SUCCESS" != $result['result_code']) {
                //pubu("订单号：{$order_no} 因{$reason} 申请的微信退款失败, 原因：{$result['return_msg']}");
                return ['status' => false, 'msg' => "订单号：{$order['transaction_id']} 因{$reason} 申请的微信退款失败, 原因：{$result['err_code_des']}"];
            } else {

                return ['status' => true, 'msg' => '退款成功'];
            }
        } catch (\Exception $e) {
            return ['status' => false, 'msg' => "订单号：{$order['transaction_id']} 因{$reason} 申请的微信退款失败, 原因：{$e->getMessage()}"];
        }
    }

}
